package bo.gustavo.scrapper.worker;

import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;

import org.apache.commons.lang.StringUtils;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

import bo.gustavo.scrapper.model.Persister;
import bo.gustavo.scrapper.model.Url;
import bo.gustavo.scrapper.util.CategoryEnum;
import bo.gustavo.scrapper.util.DataBaseAccessType;
import bo.gustavo.scrapper.util.PropertiesKeys;

/**
 * This class fetches the URLs of the apps and stores them in the database
 * 
 * @author Gustavo Vera
 * */
public class ScrapperWorker {

	private String iterationUrl;

	private String originalUrl;

	private Document document;

	private int iterationNumber = 0;

	private Properties prop;

	private CategoryEnum category;

	private int maxPages;

	private static final String PAGE_PATTERN = "%NUMBER%";

	private static final String HREF = "abs:href";

	private boolean isPaid;

	private static final int MAX_RETRY = 10;

	private static final int MAX_APPS_PER_PAGE = 24;

	public ScrapperWorker(String url, Properties prop, CategoryEnum category, boolean isPaid, int maxPages) {
		this.originalUrl = url;
		this.prop = prop;
		this.category = category;
		this.maxPages = maxPages;
		this.isPaid = isPaid;
	}

	/**
	 * This is the main method of the scrapper. It fetches all the data using
	 * css classes. The css classes are configured in he properties file
	 * */
	public void work() {
		List<Object> listToSave = new ArrayList<Object>();
		while (iterationNumber < maxPages) {
			loadDocument();
			String link = "";
			Elements contentElements = document.select(prop.getProperty(PropertiesKeys.CSS_QUERY_APP_LIST));
			listToSave.clear();
			for (Element appElement : contentElements) {
				Element elementURL = appElement.select(prop.getProperty(PropertiesKeys.CSS_QUERY_SINGLE_APP)).first();
				link = StringUtils.substringBefore(elementURL.attr(HREF), "&feat");
				Url url = new Url(elementURL.text(), link, category.name(), isPaid);
				listToSave.add(url);
			}
			if (contentElements.size() < MAX_APPS_PER_PAGE) {
				iterationNumber = maxPages + 1;
			} else {
				iterationNumber++;
			}
			Persister.getInstance().maskOperations(null, listToSave, DataBaseAccessType.SAVE_LIST);
			document = null;
		}
	}

	private void loadDocument() {
		boolean docLoaded = false;
		iterationUrl = StringUtils.replace(originalUrl, PAGE_PATTERN, Integer.toString(iterationNumber * 24));
		int retries = 0;
		while (!docLoaded) {
			try {
				document = Jsoup.parse(new URL(iterationUrl).openStream(), "UTF-8", iterationUrl);
				System.out.println("Connected to " + iterationUrl);
				System.out.println("Title of page is : " + document.title());
				docLoaded = true;
			} catch (IOException e) {
				System.out.println("Something wrong happened fetching the following url:  " + iterationUrl);
				retries++;
				if (retries == MAX_RETRY) {
					docLoaded = true;
				}
				try {
					Thread.currentThread().sleep(5000);
				} catch (InterruptedException e1) {
					e1.printStackTrace();
				}
			}
		}
	}

}
